﻿Option Explicit On
Imports System.Xml

Public Class frmEditItems

    Private saved As Boolean
    Private items(,) As Item
    Private numItems(0 To 13) As Integer
    Private maxNumItems
    Private grdArray(0 To 13) As Object
    Private slotArray(0 To 13) As String
    Private t_itemName As String
    Private curTabIndex As Integer

    Public Event EditItemsComplete()

    Private Sub setSaved(ByVal state As Boolean)
        If state = True Then
            saved = True
            Me.Text = "DK Optimize - Edit Items"
        Else
            saved = False
            Me.Text = "DK Optimize - Edit Items*"
        End If
    End Sub

    Public Sub EditItemSetup()
        ' General Setup for the grids, etc.
        ' Not a ton of setup, but it's necessary.

        Dim loopvar As Integer
        Dim ctrlFlex As Control

        ' Slot index setup since we don't have control arrays
        grdArray(0) = grdHead
        grdArray(1) = grdShoulder
        grdArray(2) = grdChest
        grdArray(3) = grdHand
        grdArray(4) = grdLeg
        grdArray(5) = grdNeck
        grdArray(6) = grdBack
        grdArray(7) = grdWrist
        grdArray(8) = grdWaist
        grdArray(9) = grdFoot
        grdArray(10) = grdFinger
        grdArray(11) = grdTrinket
        grdArray(12) = grd2HWeapon
        grdArray(13) = grd1HWeapon

        tbsItems.SelectedIndex = 0
        curTabIndex = 0

        slotArray(0) = "head"
        slotArray(1) = "shoulder"
        slotArray(2) = "chest"
        slotArray(3) = "hand"
        slotArray(4) = "leg"
        slotArray(5) = "neck"
        slotArray(6) = "back"
        slotArray(7) = "wrist"
        slotArray(8) = "waist"
        slotArray(9) = "foot"
        slotArray(10) = "finger"
        slotArray(11) = "trinket"
        slotArray(12) = "twohand"
        slotArray(13) = "onehand"

        For loopvar = 0 To 13
            numitems(loopvar) = 0
        Next
        maxNumItems = 0

        For Each ctrl In tbsItems.Controls
            For Each ctrlFlex In ctrl.Controls
                If TypeOf ctrlFlex Is FlexCell.Grid Then
                    With DirectCast(ctrlFlex, FlexCell.Grid)
                        .AutoRedraw = False
                        .ExtendLastCol = True
                        .Rows = 2
                        .FixedRows = 1
                        .BoldFixedCell = False
                        .SelectionMode = FlexCell.SelectionModeEnum.ByCell
                        .AllowUserSort = True
                        .AllowUserResizing = FlexCell.ResizeEnum.Columns
                        Select Case .Name
                            Case "grdFinger"
                                .Cols = 20
                                .Column(0).Visible = False
                                .Cell(0, 1).Text = "Item Name"
                                .Column(1).Width = 200
                                .Cell(0, 2).Text = "Unique"
                                .Column(2).Width = 60
                                .Cell(0, 3).Text = "Str"
                                .Column(3).Width = 40
                                .Cell(0, 4).Text = "AP"
                                .Column(4).Width = 40
                                .Cell(0, 5).Text = "Crit"
                                .Column(5).Width = 40
                                .Cell(0, 6).Text = "Haste"
                                .Column(6).Width = 40
                                .Cell(0, 7).Text = "ArP"
                                .Column(7).Width = 40
                                .Cell(0, 8).Text = "Agi"
                                .Column(8).Width = 40
                                .Cell(0, 9).Text = "Exp"
                                .Column(9).Width = 40
                                .Cell(0, 10).Text = "Hit"
                                .Column(10).Width = 40
                                .Cell(0, 11).Text = "Armor"
                                .Column(11).Width = 50
                                .Cell(0, 12).Text = "Socket 1"
                                .Column(12).Width = 60
                                .Cell(0, 13).Text = "Socket 2"
                                .Column(13).Width = 60
                                .Cell(0, 14).Text = "Socket 3"
                                .Column(14).Width = 60
                                .Cell(0, 15).Text = "Socket"
                                .Column(15).Width = 50
                                .Cell(0, 16).Text = "Bonus"
                                .Column(16).Width = 50
                                .Cell(0, 17).Text = "Source"
                                .Column(17).Width = 150
                                .Cell(0, 18).Text = "iLvl"
                                .Column(18).Width = 30
                                .Cell(0, 19).Text = "Wowhead ID"
                                .Column(19).Width = 70
                            Case "grdTrinket"
                                .Cols = 22
                                .Column(0).Visible = False
                                .Cell(0, 1).Text = "Item Name"
                                .Column(1).Width = 200
                                .Cell(0, 2).Text = "Proc"
                                .Column(2).Width = 40
                                .Cell(0, 3).Text = "Stat"
                                .Column(3).Width = 50
                                .Cell(0, 4).Text = "Uptime"
                                .Column(4).Width = 50
                                .Cell(0, 5).Text = "Str"
                                .Column(5).Width = 40
                                .Cell(0, 6).Text = "AP"
                                .Column(6).Width = 40
                                .Cell(0, 7).Text = "Crit"
                                .Column(7).Width = 40
                                .Cell(0, 8).Text = "Haste"
                                .Column(8).Width = 40
                                .Cell(0, 9).Text = "ArP"
                                .Column(9).Width = 40
                                .Cell(0, 10).Text = "Agi"
                                .Column(10).Width = 40
                                .Cell(0, 11).Text = "Exp"
                                .Column(11).Width = 40
                                .Cell(0, 12).Text = "Hit"
                                .Column(12).Width = 40
                                .Cell(0, 13).Text = "Armor"
                                .Column(13).Width = 50
                                .Cell(0, 14).Text = "Socket 1"
                                .Column(14).Width = 60
                                .Cell(0, 15).Text = "Socket 2"
                                .Column(15).Width = 60
                                .Cell(0, 16).Text = "Socket 3"
                                .Column(16).Width = 60
                                .Cell(0, 17).Text = "Socket"
                                .Column(17).Width = 50
                                .Cell(0, 18).Text = "Bonus"
                                .Column(18).Width = 50
                                .Cell(0, 19).Text = "Source"
                                .Column(19).Width = 150
                                .Cell(0, 20).Text = "iLvl"
                                .Column(20).Width = 30
                                .Cell(0, 21).Text = "Wowhead ID"
                                .Column(21).Width = 70
                            Case "grd2HWeapon"
                                .Cols = 22
                                .Column(0).Visible = False
                                .Cell(0, 1).Text = "Item Name"
                                .Column(1).Width = 200
                                .Cell(0, 2).Text = "Type"
                                .Column(2).Width = 50
                                .Cell(0, 3).Text = "DPS"
                                .Column(3).Width = 40
                                .Cell(0, 4).Text = "Speed"
                                .Column(4).Width = 40
                                .Cell(0, 5).Text = "Str"
                                .Column(5).Width = 40
                                .Cell(0, 6).Text = "AP"
                                .Column(6).Width = 40
                                .Cell(0, 7).Text = "Crit"
                                .Column(7).Width = 40
                                .Cell(0, 8).Text = "Haste"
                                .Column(8).Width = 40
                                .Cell(0, 9).Text = "ArP"
                                .Column(9).Width = 40
                                .Cell(0, 10).Text = "Agi"
                                .Column(10).Width = 40
                                .Cell(0, 11).Text = "Exp"
                                .Column(11).Width = 40
                                .Cell(0, 12).Text = "Hit"
                                .Column(12).Width = 40
                                .Cell(0, 13).Text = "Armor"
                                .Column(13).Width = 50
                                .Cell(0, 14).Text = "Socket 1"
                                .Column(14).Width = 60
                                .Cell(0, 15).Text = "Socket 2"
                                .Column(15).Width = 60
                                .Cell(0, 16).Text = "Socket 3"
                                .Column(16).Width = 60
                                .Cell(0, 17).Text = "Socket"
                                .Column(17).Width = 50
                                .Cell(0, 18).Text = "Bonus"
                                .Column(18).Width = 50
                                .Cell(0, 19).Text = "Source"
                                .Column(19).Width = 150
                                .Cell(0, 20).Text = "iLvl"
                                .Column(20).Width = 30
                                .Cell(0, 21).Text = "Wowhead ID"
                                .Column(21).Width = 70
                            Case "grd1HWeapon"
                                .Cols = 24
                                .Column(0).Visible = False
                                .Cell(0, 1).Text = "Item Name"
                                .Column(1).Width = 200
                                .Cell(0, 2).Text = "Type"
                                .Column(2).Width = 50
                                .Cell(0, 3).Text = "Unique"
                                .Column(3).Width = 50
                                .Cell(0, 4).Text = "Hand"
                                .Column(4).Width = 60
                                .Cell(0, 5).Text = "DPS"
                                .Column(5).Width = 40
                                .Cell(0, 6).Text = "Speed"
                                .Column(6).Width = 40
                                .Cell(0, 7).Text = "Str"
                                .Column(7).Width = 40
                                .Cell(0, 8).Text = "AP"
                                .Column(8).Width = 40
                                .Cell(0, 9).Text = "Crit"
                                .Column(9).Width = 40
                                .Cell(0, 10).Text = "Haste"
                                .Column(10).Width = 40
                                .Cell(0, 11).Text = "ArP"
                                .Column(11).Width = 40
                                .Cell(0, 12).Text = "Agi"
                                .Column(12).Width = 40
                                .Cell(0, 13).Text = "Exp"
                                .Column(13).Width = 40
                                .Cell(0, 14).Text = "Hit"
                                .Column(14).Width = 40
                                .Cell(0, 15).Text = "Armor"
                                .Column(15).Width = 50
                                .Cell(0, 16).Text = "Socket 1"
                                .Column(16).Width = 60
                                .Cell(0, 17).Text = "Socket 2"
                                .Column(17).Width = 60
                                .Cell(0, 18).Text = "Socket 3"
                                .Column(18).Width = 60
                                .Cell(0, 19).Text = "Socket"
                                .Column(19).Width = 50
                                .Cell(0, 20).Text = "Bonus"
                                .Column(20).Width = 50
                                .Cell(0, 21).Text = "Source"
                                .Column(21).Width = 150
                                .Cell(0, 22).Text = "iLvl"
                                .Column(22).Width = 30
                                .Cell(0, 23).Text = "Wowhead ID"
                                .Column(23).Width = 70
                            Case Else
                                .Cols = 19
                                .Column(0).Visible = False
                                .Cell(0, 1).Text = "Item Name"
                                .Column(1).Width = 200
                                .Cell(0, 2).Text = "Str"
                                .Column(2).Width = 40
                                .Cell(0, 3).Text = "AP"
                                .Column(3).Width = 40
                                .Cell(0, 4).Text = "Crit"
                                .Column(4).Width = 40
                                .Cell(0, 5).Text = "Haste"
                                .Column(5).Width = 40
                                .Cell(0, 6).Text = "ArP"
                                .Column(6).Width = 40
                                .Cell(0, 7).Text = "Agi"
                                .Column(7).Width = 40
                                .Cell(0, 8).Text = "Exp"
                                .Column(8).Width = 40
                                .Cell(0, 9).Text = "Hit"
                                .Column(9).Width = 40
                                .Cell(0, 10).Text = "Armor"
                                .Column(10).Width = 50
                                .Cell(0, 11).Text = "Socket 1"
                                .Column(11).Width = 60
                                .Cell(0, 12).Text = "Socket 2"
                                .Column(12).Width = 60
                                .Cell(0, 13).Text = "Socket 3"
                                .Column(13).Width = 60
                                .Cell(0, 14).Text = "Socket"
                                .Column(14).Width = 50
                                .Cell(0, 15).Text = "Bonus"
                                .Column(15).Width = 50
                                .Cell(0, 16).Text = "Source"
                                .Column(16).Width = 150
                                .Cell(0, 17).Text = "iLvl"
                                .Column(17).Width = 30
                                .Cell(0, 18).Text = "Wowhead ID"
                                .Column(18).Width = 70
                        End Select

                        ' Loop through every column in the grid.
                        ' Set the column type for that grid depending
                        ' on the header text of the grid. neato.
                        For loopvar = 1 To .Cols - 1
                            Select Case .Cell(0, loopvar).Text
                                Case "Socket 1", "Socket 2", "Socket 3"
                                    .Column(loopvar).CellType = FlexCell.CellTypeEnum.ComboBox
                                    .ComboBox(loopvar).Items.Clear()
                                    .ComboBox(loopvar).Items.Add("None")
                                    .ComboBox(loopvar).Items.Add("Red")
                                    .ComboBox(loopvar).Items.Add("Yellow")
                                    .ComboBox(loopvar).Items.Add("Blue")
                                    .ComboBox(loopvar).Items.Add("Prismatic")
                                Case "Bonus", "Stat"
                                    .Column(loopvar).CellType = FlexCell.CellTypeEnum.ComboBox
                                    .ComboBox(loopvar).Items.Clear()
                                    .ComboBox(loopvar).Items.Add("None")
                                    .ComboBox(loopvar).Items.Add("Str")
                                    .ComboBox(loopvar).Items.Add("AP")
                                    .ComboBox(loopvar).Items.Add("Crit")
                                    .ComboBox(loopvar).Items.Add("Haste")
                                    .ComboBox(loopvar).Items.Add("ArP")
                                    .ComboBox(loopvar).Items.Add("Agi")
                                    .ComboBox(loopvar).Items.Add("Exp")
                                    .ComboBox(loopvar).Items.Add("Hit")
                                Case "Hand"
                                    .Column(loopvar).CellType = FlexCell.CellTypeEnum.ComboBox
                                    .ComboBox(loopvar).Items.Clear()
                                    .ComboBox(loopvar).Items.Add("None")
                                    .ComboBox(loopvar).Items.Add("One Hand")
                                    .ComboBox(loopvar).Items.Add("Main Hand")
                                    .ComboBox(loopvar).Items.Add("Off Hand")
                                Case "Type" ' Need a little more logic here so polearm doesn't show up in 1H
                                    .Column(loopvar).CellType = FlexCell.CellTypeEnum.ComboBox
                                    .ComboBox(loopvar).Items.Clear()
                                    .ComboBox(loopvar).Items.Add("None")
                                    .ComboBox(loopvar).Items.Add("Axe")
                                    .ComboBox(loopvar).Items.Add("Sword")
                                    .ComboBox(loopvar).Items.Add("Mace")
                                    If .Name = "grd2HWeapon" Then
                                        .ComboBox(loopvar).Items.Add("Polearm")
                                    End If
                                Case "Unique"
                                    .Column(loopvar).CellType = FlexCell.CellTypeEnum.ComboBox
                                    .ComboBox(loopvar).Items.Clear()
                                    .ComboBox(loopvar).Items.Add("No")
                                    .ComboBox(loopvar).Items.Add("Yes")
                                Case Else
                                    ' Value, no nothing
                            End Select
                        Next

                        .AutoRedraw = True
                        .Refresh()
                    End With
                End If
            Next
        Next

        setSaved(True)

    End Sub

    Public Sub AddItem(ByVal inItem As Item, ByVal slot As String)
        ' Add items to the correct index in items() so that we can keep track.
        Dim slotIndex As Integer

        Select Case slot
            Case "head"
                slotIndex = 0
            Case "shoulder"
                slotIndex = 1
            Case "chest"
                slotIndex = 2
            Case "hand"
                slotIndex = 3
            Case "leg"
                slotIndex = 4
            Case "neck"
                slotIndex = 5
            Case "back"
                slotIndex = 6
            Case "wrist"
                slotIndex = 7
            Case "waist"
                slotIndex = 8
            Case "foot"
                slotIndex = 9
            Case "finger"
                slotIndex = 10
            Case "trinket"
                slotIndex = 11
            Case "twohand"
                slotIndex = 12
            Case "onehand"
                slotIndex = 13
        End Select

        numItems(slotIndex) += 1
        If numItems(slotIndex) > maxNumItems Then
            ReDim Preserve items(0 To 13, 0 To maxNumItems)
            maxNumItems = numItems(slotIndex)
        End If

        items(slotIndex, numItems(slotIndex) - 1) = New Item
        items(slotIndex, numItems(slotIndex) - 1) = inItem.clone

    End Sub

    Public Sub DisplayItems()
        ' Displays all the items in the items() array in the correct spot on the 
        ' correct tab

        Dim loopvar As Integer
        Dim loopvar2 As Integer

        For loopvar = 0 To 13
            DirectCast(grdArray(loopvar), FlexCell.Grid).Rows = 1 + numItems(loopvar)
            For loopvar2 = 0 To numItems(loopvar) - 1
                items(loopvar, loopvar2).showStatic(grdArray(loopvar), loopvar2 + 1, 1, slotArray(loopvar), True)
            Next
            ' Sort by iLvl, which is the second-to-last column now.
            DirectCast(grdArray(loopvar), FlexCell.Grid).Column(DirectCast(grdArray(loopvar), FlexCell.Grid).Cols - 2).Sort(FlexCell.SortEnum.Descending)
        Next


    End Sub

    Private Sub frmEditItems_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        ' Checked saved, warn the user, cancel if they don't want to go.
        Dim msgresult As DialogResult

        Dim curGrid As FlexCell.Grid

        ' Clear the current cell so that we can be sure things are working.
        curGrid = DirectCast(grdArray(tbsItems.SelectedIndex), FlexCell.Grid)
        curGrid.Cell(curGrid.ActiveCell.Row, 0).SetFocus()

        ' If there was an error, activecell will still have a value.
        If curGrid.ActiveCell.Col <> 0 Then
            e.Cancel = True
            Exit Sub
        End If

        If saved = False Then
            msgresult = MessageBox.Show("Items are not saved.  Would you like to save Item information?", "DK Optimize", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1)
            Select Case msgresult
                Case Windows.Forms.DialogResult.Cancel
                    e.Cancel = True
                Case Windows.Forms.DialogResult.Yes
                    saveItems()
                    setSaved(True)
                    e.Cancel = False
                    Me.Hide()
                    RaiseEvent EditItemsComplete()
                Case Windows.Forms.DialogResult.No
                    e.Cancel = False
                    Me.Hide()
                    RaiseEvent EditItemsComplete()
            End Select
        Else
            e.Cancel = False
            Me.Hide()
            RaiseEvent EditItemsComplete()
        End If

    End Sub

    Private Sub btnSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSave.Click
        ' Writes back out to the XML file data.xml  Just replaces the items part with
        ' the current contents of items()
        Dim msgResult As DialogResult

        Dim curGrid As FlexCell.Grid

        ' Clear the current cell so that we can be sure things are working.
        curGrid = DirectCast(grdArray(tbsItems.SelectedIndex), FlexCell.Grid)
        curGrid.Cell(curGrid.ActiveCell.Row, 0).SetFocus()
        If curGrid.ActiveCell.Col <> 0 Then Exit Sub

        msgResult = MessageBox.Show("Are you sure you want to save all items?", "DK Optimize", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1)
        If msgResult = Windows.Forms.DialogResult.No Then Exit Sub

        saveItems()
        setSaved(True)
    End Sub

    Private Sub saveItems()
        ' does the actual work of saving.
        Dim loopvar As Integer, loopvar2 As Integer
        Dim xmlWriter As New XmlTextWriter(Windows.Forms.Application.CommonAppDataPath & "\data_items.xml", System.Text.Encoding.UTF8)
        Dim buildinfo As FileVersionInfo = FileVersionInfo.GetVersionInfo(Windows.Forms.Application.ExecutablePath)

        xmlWriter.WriteStartDocument()
        xmlWriter.WriteWhitespace(vbNewLine)
        xmlWriter.WriteStartElement("items")
        xmlWriter.WriteAttributeString("version", buildinfo.ProductVersion)
        For loopvar = 0 To 13
            xmlWriter.WriteWhitespace(vbNewLine)
            xmlWriter.WriteWhitespace(vbTab)
            xmlWriter.WriteStartElement(slotArray(loopvar))
            For loopvar2 = 0 To numItems(loopvar) - 1
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab)
                xmlWriter.WriteStartElement("item")
                xmlWriter.WriteAttributeString("name", items(loopvar, loopvar2).name)
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("str", items(loopvar, loopvar2).str.ToString(System.Globalization.CultureInfo.InvariantCulture))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("ap", items(loopvar, loopvar2).ap.ToString(System.Globalization.CultureInfo.InvariantCulture))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("crit", items(loopvar, loopvar2).crit.ToString(System.Globalization.CultureInfo.InvariantCulture))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("haste", items(loopvar, loopvar2).haste.ToString(System.Globalization.CultureInfo.InvariantCulture))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("arp", items(loopvar, loopvar2).arp.ToString(System.Globalization.CultureInfo.InvariantCulture))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("agi", items(loopvar, loopvar2).agi.ToString(System.Globalization.CultureInfo.InvariantCulture))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("exp", items(loopvar, loopvar2).exp.ToString(System.Globalization.CultureInfo.InvariantCulture))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("hit", items(loopvar, loopvar2).hit.ToString(System.Globalization.CultureInfo.InvariantCulture))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("armor", items(loopvar, loopvar2).armor.ToString(System.Globalization.CultureInfo.InvariantCulture))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("socket1", items(loopvar, loopvar2).getColor(0))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("socket2", items(loopvar, loopvar2).getColor(1))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("socket3", items(loopvar, loopvar2).getColor(2))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("socket", items(loopvar, loopvar2).socketbonus.ToString(System.Globalization.CultureInfo.InvariantCulture))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("bonus", items(loopvar, loopvar2).getSocketStat)
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("source", items(loopvar, loopvar2).source)
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("ilvl", items(loopvar, loopvar2).ilvl.ToString(System.Globalization.CultureInfo.InvariantCulture))
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                xmlWriter.WriteElementString("wowheadid", items(loopvar, loopvar2).wowheadID.ToString(System.Globalization.CultureInfo.InvariantCulture))
                ' Now we write out the extra characteristics for ring / trinket / weapons
                Select Case slotArray(loopvar)
                    Case "finger"
                        xmlWriter.WriteWhitespace(vbNewLine)
                        xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                        xmlWriter.WriteElementString("unique", items(loopvar, loopvar2).unique)
                    Case "trinket"
                        xmlWriter.WriteWhitespace(vbNewLine)
                        xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                        xmlWriter.WriteElementString("proc", items(loopvar, loopvar2).procvalue.ToString(System.Globalization.CultureInfo.InvariantCulture))
                        xmlWriter.WriteWhitespace(vbNewLine)
                        xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                        xmlWriter.WriteElementString("procstat", items(loopvar, loopvar2).getprocStat)
                        xmlWriter.WriteWhitespace(vbNewLine)
                        xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                        xmlWriter.WriteElementString("uptime", items(loopvar, loopvar2).procuptime.ToString(System.Globalization.CultureInfo.InvariantCulture))
                    Case "twohand"
                        xmlWriter.WriteWhitespace(vbNewLine)
                        xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                        xmlWriter.WriteElementString("weptype", items(loopvar, loopvar2).getWepType)
                        xmlWriter.WriteWhitespace(vbNewLine)
                        xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                        xmlWriter.WriteElementString("wepdps", items(loopvar, loopvar2).wepdps.ToString(System.Globalization.CultureInfo.InvariantCulture))
                        xmlWriter.WriteWhitespace(vbNewLine)
                        xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                        xmlWriter.WriteElementString("wepspeed", items(loopvar, loopvar2).wepspeed.ToString(System.Globalization.CultureInfo.InvariantCulture))
                    Case "onehand"
                        xmlWriter.WriteWhitespace(vbNewLine)
                        xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                        xmlWriter.WriteElementString("unique", items(loopvar, loopvar2).unique)
                        xmlWriter.WriteWhitespace(vbNewLine)
                        xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                        xmlWriter.WriteElementString("weptype", items(loopvar, loopvar2).getWepType)
                        xmlWriter.WriteWhitespace(vbNewLine)
                        xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                        xmlWriter.WriteElementString("wepdps", items(loopvar, loopvar2).wepdps.ToString(System.Globalization.CultureInfo.InvariantCulture))
                        xmlWriter.WriteWhitespace(vbNewLine)
                        xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                        xmlWriter.WriteElementString("wepspeed", items(loopvar, loopvar2).wepspeed.ToString(System.Globalization.CultureInfo.InvariantCulture))
                        xmlWriter.WriteWhitespace(vbNewLine)
                        xmlWriter.WriteWhitespace(vbTab & vbTab & vbTab)
                        xmlWriter.WriteElementString("wephand", items(loopvar, loopvar2).getWepHand)
                    Case Else
                        ' nothing extra for the standard ones
                End Select
                xmlWriter.WriteWhitespace(vbNewLine)
                xmlWriter.WriteWhitespace(vbTab & vbTab)
                xmlWriter.WriteEndElement()
            Next
            xmlWriter.WriteWhitespace(vbNewLine)
            xmlWriter.WriteWhitespace(vbTab)
            xmlWriter.WriteEndElement()
        Next
        xmlWriter.WriteWhitespace(vbNewLine)
        xmlWriter.WriteEndElement()
        xmlWriter.WriteEndDocument()
        xmlWriter.Close()
    End Sub

    Private Sub grd_LeaveCell(ByVal Sender As Object, ByVal e As FlexCell.Grid.LeaveCellEventArgs) Handles grdHead.LeaveCell, grdShoulder.LeaveCell, grdChest.LeaveCell, grdHand.LeaveCell, grdLeg.LeaveCell, grdNeck.LeaveCell, grdBack.LeaveCell, grdWrist.LeaveCell, grdWaist.LeaveCell, grdFoot.LeaveCell, grdFinger.LeaveCell, grdTrinket.LeaveCell, grd2HWeapon.LeaveCell, grd1HWeapon.LeaveCell

        ' Set the property.  t_gemName as the old gem name for matching purposes.
        Dim curItemIndex As Integer
        Dim nameString As String
        Dim curGrid As FlexCell.Grid

        curGrid = DirectCast(Sender, FlexCell.Grid)
        'Default values.  If you leave a text cell
        ' it will stay blank.  If you leave a numeric cell
        ' it will be 0, color cell will be none. And a boolean cell will be no.

        ' Don't do anything if we're out.
        If curGrid.ActiveCell.Row = 0 Then Exit Sub

        If curGrid.ActiveCell.Text = "" Then
            Select Case curGrid.Cell(0, curGrid.ActiveCell.Col).Text
                Case "Item Name", "Source"
                    curGrid.ActiveCell.Text = ""
                Case "Unique"
                    curGrid.ActiveCell.Text = "No"
                Case "Type"
                    curGrid.ActiveCell.Text = "None"
                Case "Hand"
                    curGrid.ActiveCell.Text = "None"
                Case "Socket 1", "Socket 2", "Socket 3"
                    curGrid.ActiveCell.Text = "None"
                Case "Stat", "Bonus"
                    curGrid.ActiveCell.Text = "None"
                Case Else
                    ' Numeric Cells are set to zero
                    curGrid.ActiveCell.Text = "0"
            End Select
        End If

        If isValidValue(curGrid.ActiveCell, curGrid) = False Then
            tbsItems.SelectedIndex = curTabIndex
            curTabIndex = tbsItems.SelectedIndex
            If curGrid.ActiveCell.Col <> 1 Then
                MessageBox.Show("Invalid Cell Value. Please enter a different value.", "DK Optimize", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1)
            Else
                MessageBox.Show("Item name already exists.  Please select a different name.", "DK Optimize", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1)
            End If

            e.Cancel = True
        Else
            If e.Col = 1 Then
                nameString = t_itemName
            Else
                nameString = curGrid.Cell(curGrid.ActiveCell.Row, 1).Text
            End If

            curItemIndex = ChangeProperty(nameString, curGrid.ActiveCell.Col, curGrid.ActiveCell.Row, curGrid)

            If curGrid.Cell(0, curGrid.ActiveCell.Col).Text = "Socket 1" Or _
               curGrid.Cell(0, curGrid.ActiveCell.Col).Text = "Socket 2" Or _
               curGrid.Cell(0, curGrid.ActiveCell.Col).Text = "Socket 3" Then
                Dim socketIndex As Integer
                Select Case curGrid.Cell(0, curGrid.ActiveCell.Col).Text
                    Case "Socket 1"
                        socketIndex = 0
                    Case "Socket 2"
                        socketIndex = 1
                    Case "Socket 3"
                        socketIndex = 2
                End Select
                Dim slotIndex As Integer

                'Need to figure out what slot this is.  Need to pull from the
                ' grid name property.
                Select Case curGrid.Name
                    Case "grdHead"
                        slotIndex = 0
                    Case "grdShoulder"
                        slotIndex = 1
                    Case "grdChest"
                        slotIndex = 2
                    Case "grdHand"
                        slotIndex = 3
                    Case "grdLeg"
                        slotIndex = 4
                    Case "grdNeck"
                        slotIndex = 5
                    Case "grdBack"
                        slotIndex = 6
                    Case "grdWrist"
                        slotIndex = 7
                    Case "grdWaist"
                        slotIndex = 8
                    Case "grdFoot"
                        slotIndex = 9
                    Case "grdFinger"
                        slotIndex = 10
                    Case "grdTrinket"
                        slotIndex = 11
                    Case "grd2HWeapon"
                        slotIndex = 12
                    Case "grd1HWeapon"
                        slotIndex = 13
                End Select
                curGrid.Cell(curGrid.ActiveCell.Row, curGrid.ActiveCell.Col).BackColor = items(slotIndex, curItemIndex).RGBColor(socketIndex)
            End If
        End If

    End Sub

    Private Sub grd_RowColChange(ByVal Sender As Object, ByVal e As FlexCell.Grid.RowColChangeEventArgs) Handles grdHead.RowColChange, grdShoulder.RowColChange, grdChest.RowColChange, grdHand.RowColChange, grdLeg.RowColChange, grdNeck.RowColChange, grdBack.RowColChange, grdWrist.RowColChange, grdWaist.RowColChange, grdFoot.RowColChange, grdFinger.RowColChange, grdTrinket.RowColChange, grd2HWeapon.RowColChange, grd1HWeapon.RowColChange

        Dim curGrid As FlexCell.Grid
        curGrid = DirectCast(Sender, FlexCell.Grid)
        ' Check name
        If curGrid.ActiveCell.Col = 1 Then
            t_itemName = curGrid.ActiveCell.Text
        End If
    End Sub

    Private Function isValidValue(ByVal cell As FlexCell.Cell, ByVal curGrid As FlexCell.Grid) As Boolean
        ' Check for validity of the value in the cell passed in.  Use row / etc to check it.
        If cell.Row = 0 Then
            isValidValue = True
            Exit Function
        End If
        If cell.Col = 0 Then
            isValidValue = True
            Exit Function
        End If
        Select Case curGrid.Cell(0, cell.Col).Text
            Case "Item Name"
                Dim loopvar As Integer
                For loopvar = 1 To curGrid.Rows - 1
                    If curGrid.Cell(loopvar, 1).Text = cell.Text And loopvar <> cell.Row Then
                        isValidValue = False
                        Exit Function
                    End If
                Next
                isValidValue = True
            Case "Source"
                isValidValue = True
            Case "Unique"
                If cell.Text <> "Yes" And cell.Text <> "No" Then
                    isValidValue = False
                Else
                    isValidValue = True
                End If
            Case "Type"
                If cell.Text <> "None" And cell.Text <> "Axe" And cell.Text <> "Mace" And cell.Text <> "Sword" Then
                    If curGrid.Name = "grd2HWeapon" And cell.Text = "Polearm" Then
                        isValidValue = True
                    Else
                        isValidValue = False
                    End If
                Else
                    isValidValue = True
                End If
            Case "Hand"
                If cell.Text <> "One Hand" And cell.Text <> "Main Hand" And cell.Text <> "Off Hand" And cell.Text <> "None" Then
                    isValidValue = False
                Else
                    isValidValue = True
                End If
            Case "Socket 1", "Socket 2", "Socket 3"
                If cell.Text <> "None" And cell.Text <> "Red" And cell.Text <> "Blue" And cell.Text <> "Prismatic" And cell.Text <> "Yellow" Then
                    isValidValue = False
                Else
                    isValidValue = True
                End If
            Case "Stat", "Bonus"
                If cell.Text <> "None" And cell.Text <> "Str" And cell.Text <> "AP" And cell.Text <> "Crit" And cell.Text <> "Haste" And cell.Text <> "ArP" And cell.Text <> "Agi" And cell.Text <> "Exp" And cell.Text <> "Hit" Then
                    isValidValue = False
                Else
                    isValidValue = True
                End If
            Case "Wowhead ID"
                If IsNumeric(cell.Text) = False Or Double.Parse(cell.Text) < 0 Or Double.Parse(cell.Text) > 1000000 Then
                    isValidValue = False
                Else
                    isValidValue = True
                End If
            Case Else
                If IsNumeric(cell.Text) = False Or Double.Parse(cell.Text) < 0 Or Double.Parse(cell.Text) > 10000 Then
                    isValidValue = False
                Else
                    isValidValue = True
                End If
        End Select
    End Function

    Private Function ChangeProperty(ByVal itemName As String, ByVal col As Integer, ByVal row As Integer, ByVal curGrid As FlexCell.Grid) As Integer
        ' Searches for a gem by name in the gems() array in case of sorting, and then
        ' updates it.
        Dim ItemIndex As Integer
        Dim loopvar As Integer
        Dim newProp As String
        Dim slotIndex As Integer

        'Need to figure out what slot this is.  Need to pull from the
        ' grid name property.
        Select Case curGrid.Name
            Case "grdHead"
                slotIndex = 0
            Case "grdShoulder"
                slotIndex = 1
            Case "grdChest"
                slotIndex = 2
            Case "grdHand"
                slotIndex = 3
            Case "grdLeg"
                slotIndex = 4
            Case "grdNeck"
                slotIndex = 5
            Case "grdBack"
                slotIndex = 6
            Case "grdWrist"
                slotIndex = 7
            Case "grdWaist"
                slotIndex = 8
            Case "grdFoot"
                slotIndex = 9
            Case "grdFinger"
                slotIndex = 10
            Case "grdTrinket"
                slotIndex = 11
            Case "grd2HWeapon"
                slotIndex = 12
            Case "grd1HWeapon"
                slotIndex = 13
        End Select

        For loopvar = 0 To numItems(slotIndex) - 1
            If items(slotIndex, loopvar).name = itemName Then
                ItemIndex = loopvar
            End If
        Next

        newProp = curGrid.Cell(row, col).Text

        With items(slotIndex, ItemIndex)
            Select Case curGrid.Cell(0, col).Text
                Case "Item Name"
                    If .name <> newProp Then setSaved(False)
                    .name = newProp
                Case "Str"
                    If .str <> Double.Parse(newProp) Then setSaved(False)
                    .str = Double.Parse(newProp)
                Case "AP"
                    If .ap <> Double.Parse(newProp) Then setSaved(False)
                    .ap = Double.Parse(newProp)
                Case "Crit"
                    If .crit <> Double.Parse(newProp) Then setSaved(False)
                    .crit = Double.Parse(newProp)
                Case "Haste"
                    If .haste <> Double.Parse(newProp) Then setSaved(False)
                    .haste = Double.Parse(newProp)
                Case "ArP"
                    If .arp <> Double.Parse(newProp) Then setSaved(False)
                    .arp = Double.Parse(newProp)
                Case "Agi"
                    If .agi <> Double.Parse(newProp) Then setSaved(False)
                    .agi = Double.Parse(newProp)
                Case "Exp"
                    If .exp <> Double.Parse(newProp) Then setSaved(False)
                    .exp = Double.Parse(newProp)
                Case "Hit"
                    If .hit <> Double.Parse(newProp) Then setSaved(False)
                    .hit = Double.Parse(newProp)
                Case "Armor"
                    If .armor <> Double.Parse(newProp) Then setSaved(False)
                    .armor = Double.Parse(newProp)
                Case "Socket 1"
                    If .getColor(0) <> newProp Then setSaved(False)
                    .setColor(0, newProp)
                Case "Socket 2"
                    If .getColor(1) <> newProp Then setSaved(False)
                    .setColor(1, newProp)
                Case "Socket 3"
                    If .getColor(2) <> newProp Then setSaved(False)
                    .setColor(2, newProp)
                Case "Socket"
                    If .socketbonus <> Double.Parse(newProp) Then setSaved(False)
                    .socketbonus = Double.Parse(newProp)
                Case "Bonus"
                    If .getSocketStat <> newProp Then setSaved(False)
                    .setSocketStat(newProp)
                Case "Source"
                    If .source <> newProp Then setSaved(False)
                    .source = newProp
                Case "iLvl"
                    If .ilvl <> Double.Parse(newProp) Then setSaved(False)
                    .ilvl = Double.Parse(newProp)
                Case "Unique"
                    If .getUnique_YN <> newProp Then setSaved(False)
                    If newProp = "Yes" Then
                        .unique = True
                    Else
                        .unique = False
                    End If
                Case "Proc"
                    If .procvalue <> Double.Parse(newProp) Then setSaved(False)
                    .procvalue = Double.Parse(newProp)
                Case "Stat"
                    If .getprocStat <> newProp Then setSaved(False)
                    .setProcStat(newProp)
                Case "Uptime"
                    If .procuptime <> Double.Parse(newProp) Then setSaved(False)
                    .procuptime = Double.Parse(newProp)
                Case "Type"
                    If .getWepType <> newProp Then setSaved(False)
                    .setWepType(newProp)
                Case "DPS"
                    If .wepdps <> Double.Parse(newProp) Then setSaved(False)
                    .wepdps = Double.Parse(newProp)
                Case "Speed"
                    If .wepspeed <> Double.Parse(newProp) Then setSaved(False)
                    .wepspeed = Double.Parse(newProp)
                Case "Hand"
                    If .getWepHand <> newProp Then setSaved(False)
                    .setWepHand(newProp)
                Case "Wowhead ID"
                    If .wowheadID <> Double.Parse(newProp) Then setSaved(False)
                    .wowheadID = Double.Parse(newProp)
            End Select
        End With

        ChangeProperty = ItemIndex

    End Function

    Private Sub tbsItems_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles tbsItems.SelectedIndexChanged
        ' Set the active cell on the one we are leaving so verify.
        If curTabIndex <> tbsItems.SelectedIndex Then
            DirectCast(grdArray(curTabIndex), FlexCell.Grid).Cell(DirectCast(grdArray(curTabIndex), FlexCell.Grid).ActiveCell.Row, 0).SetFocus()
        End If
        curTabIndex = tbsItems.SelectedIndex
    End Sub

    Private Sub btnAdd_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAdd.Click
        ' Adds a row to the grid and takes a name from the user for the new item.  
        ' Sets the colors to none, booleans to no, and other values to none.
        Dim inputResult As String
        Dim curGrid As FlexCell.Grid

        curGrid = DirectCast(grdArray(tbsItems.SelectedIndex), FlexCell.Grid)

        ' move the focus off screen since we left the control.
        ' This also calls leave_cell, which updates our variables etc.
        curGrid.Cell(curGrid.ActiveCell.Row, 0).SetFocus()
        If curGrid.ActiveCell.Col <> 0 Then Exit Sub

        inputResult = InputBox("Please enter a name for the new Item:", "DK Optimize")

        If inputResult <> "" Then
            Dim loopvar As Integer
            For loopvar = 1 To curGrid.Rows - 1
                If curGrid.Cell(loopvar, 1).Text = inputResult Then
                    MessageBox.Show("Item name already exists.  Please select a different name.", "DK Optimize", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1)
                    Exit Sub
                End If
            Next
            Dim tempItem As Item
            tempItem = New Item
            tempItem.Clear()
            tempItem.name = inputResult
            numItems(tbsItems.SelectedIndex) += 1
            If numItems(tbsItems.SelectedIndex) > maxNumItems Then
                ReDim Preserve items(0 To 13, 0 To numItems(tbsItems.SelectedIndex) - 1)
                maxNumItems = numItems(tbsItems.SelectedIndex)
            End If
            items(tbsItems.SelectedIndex, numItems(tbsItems.SelectedIndex) - 1) = tempItem
            curGrid.Rows += 1
            items(tbsItems.SelectedIndex, numItems(tbsItems.SelectedIndex) - 1).showStatic(curGrid, curGrid.Rows - 1, 1, slotArray(tbsItems.SelectedIndex), True)
            setSaved(False)
        End If
    End Sub

    Private Sub btnDel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDel.Click
        ' Verifies, and then deletes if necessary
        ' an item from the group and more importantly
        ' the array.
        Dim msgResult As DialogResult
        Dim curGrid As FlexCell.Grid

        curGrid = DirectCast(grdArray(tbsItems.SelectedIndex), FlexCell.Grid)

        ' move the focus off screen since we left hte control.
        ' This also calls leave_cell, which updates our variables etc.
        curGrid.Cell(curGrid.ActiveCell.Row, 0).SetFocus()
        If curGrid.ActiveCell.Col <> 0 Then Exit Sub

        If curGrid.ActiveCell.Row = 0 Then Exit Sub

        msgResult = MessageBox.Show("Are you sure you want to delete """ & curGrid.Cell(curGrid.ActiveCell.Row, 1).Text & """?", "DK Optimize", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2)
        If msgResult = Windows.Forms.DialogResult.No Then Exit Sub

        Dim loopvar As Integer
        Dim curItemIndex As Integer

        For loopvar = 0 To numItems(tbsItems.SelectedIndex) - 1
            If items(tbsItems.SelectedIndex, loopvar).name = curGrid.Cell(curGrid.ActiveCell.Row, 1).Text Then
                curItemIndex = loopvar
            End If
        Next

        curGrid.RemoveItem(curGrid.ActiveCell.Row)
        For loopvar = curItemIndex To numItems(tbsItems.SelectedIndex) - 2
            items(tbsItems.SelectedIndex, loopvar) = items(tbsItems.SelectedIndex, loopvar + 1)
        Next
        numItems(tbsItems.SelectedIndex) -= 1
        setSaved(False)
    End Sub
End Class